#include <stdlib.h>
#include <stdio.h>
#include "../include/mergeToVx.h"/*winie*/
#include "../include/busapi.h"


#include "../include/wtapi_type.h"
#include "../include/host_cmd.h"
#include "../include/host_cmd_1553b.h"
#include "../include/wt_1553b.h"
#include "../include/wtapi_lowlevel.h"
#include "../include/wt_dm642.h"
SEM_ID sync_sem;
int sem_flag = 0;
static struct	PCI_CONFIG_HEADER_0 pci_config[nMaxDevice];
static struct	WT_DSP_Host_Cmd *pCmd[nMaxDevice];
static struct	WT_1553B_Board	*p1553b_card[nMaxDevice];

typedef  int  (*UserHandle)(unsigned int device,API_INT_FIFO *pINTFIFO);

static	UINT	Device_Init[nMaxDevice];
static	UINT	Channle_Init[nMaxDevice][nMax_CH1553];

static	UINT cardnum_device[nMaxDevice*nMax_CH1553];
static	UINT cardnum_ch[nMaxDevice*nMax_CH1553];

static	volatile struct	WT_1553B_Data		*wt_1553B[nMaxDevice*nMax_CH1553];
static	volatile struct	WT_IRQ_Fifo_Info	*irqfifo[nMaxDevice*nMax_CH1553];	
static	volatile struct	WT1553_Msg			*BM_Msg[nMaxDevice*nMax_CH1553];
static	UserHandle							pUserHandle[nMaxDevice*nMax_CH1553][nMaxHandle];
static	API_INT_FIFO						*UserParam[nMaxDevice*nMax_CH1553][nMaxHandle];
static	UINT								WT1553_Mode[nMaxDevice*nMax_CH1553];

static	UINT								irqfifo_rdidx[nMaxDevice*nMax_CH1553];
static	UINT								bm_rdidx[nMaxDevice*nMax_CH1553];

static	UINT								cardnum_map[nMaxDevice*nMax_CH1553];

//static	UINT								bc_enable[nMaxDevice*nMax_CH1553]={0,};
//static	UINT								rt_enable[nMaxDevice*nMax_CH1553]={0,};
static	UINT								bm_enable[nMaxDevice*nMax_CH1553]={0,};
//static struct WT_API_BC_Frame_Info L_miniFrameInfo[SubSysMode_Num];

static void  WT_1553B_Get_Board_Config(UINT device,UINT *mode)
{
	/*	
	struct WT_BOARD_CONFIG bd_config;
	WT_DM642_Get_Board_Config(device,&bd_config);
	for(UINT ch=0;ch<nMax_CH1553;ch++)
	{
		mode[ch]=None_Function;
	}
	if(bd_config.M_1553B>0)	
	{
		mode[0]=Multi_Function;
		mode[1]=Multi_Function;
	}
	else					
	{
		mode[0]=Single_Function;
		mode[1]=Single_Function;
	}
	*/
	mode[0]=Multi_Function;
	mode[1]=Multi_Function;
}

#define HANDLE_IDX	(0*nMax_CH1553+0)
	static int  __stdcall Local_Handle_00(unsigned int device)
	#include	"wt_1553b_handle.h"	 
#undef HANDLE_IDX
#define HANDLE_IDX	(0*nMax_CH1553+1)
	static int  __stdcall Local_Handle_01(unsigned int device)
	#include	"wt_1553b_handle.h"	 
#undef HANDLE_IDX

#define HANDLE_IDX	(1*nMax_CH1553+0)
	static int  __stdcall Local_Handle_10(unsigned int device)
	#include	"wt_1553b_handle.h"	 
#undef HANDLE_IDX
#define HANDLE_IDX	(1*nMax_CH1553+1)
	static int  __stdcall Local_Handle_11(unsigned int device)
	#include	"wt_1553b_handle.h"	 
#undef HANDLE_IDX

#define HANDLE_IDX	(2*nMax_CH1553+0)
	static int  __stdcall Local_Handle_20(unsigned int device)
	#include	"wt_1553b_handle.h"	 
#undef HANDLE_IDX
#define HANDLE_IDX	(2*nMax_CH1553+1)
	static int  __stdcall Local_Handle_21(unsigned int device)
	#include	"wt_1553b_handle.h"	 
#undef HANDLE_IDX

#define HANDLE_IDX	(3*nMax_CH1553+0)
	static int  __stdcall Local_Handle_30(unsigned int device)
	#include	"wt_1553b_handle.h"	 
#undef HANDLE_IDX
#define HANDLE_IDX	(3*nMax_CH1553+1)
	static int  __stdcall Local_Handle_31(unsigned int device)
	#include	"wt_1553b_handle.h"	 
#undef HANDLE_IDX

#define HANDLE_IDX	(4*nMax_CH1553+0)
	static int  __stdcall Local_Handle_40(unsigned int device)
	#include	"wt_1553b_handle.h"	 
#undef HANDLE_IDX
#define HANDLE_IDX	(4*nMax_CH1553+1)
	static int  __stdcall Local_Handle_41(unsigned int device)
	#include	"wt_1553b_handle.h"	 
#undef HANDLE_IDX

#define HANDLE_IDX	(5*nMax_CH1553+0)
	static int  __stdcall Local_Handle_50(unsigned int device)
	#include	"wt_1553b_handle.h"	 
#undef HANDLE_IDX
#define HANDLE_IDX	(5*nMax_CH1553+1)
	static int  __stdcall Local_Handle_51(unsigned int device)
	#include	"wt_1553b_handle.h"	 
#undef HANDLE_IDX

#define HANDLE_IDX	(6*nMax_CH1553+0)
	static int  __stdcall Local_Handle_60(unsigned int device)
	#include	"wt_1553b_handle.h"	 
#undef HANDLE_IDX
#define HANDLE_IDX	(6*nMax_CH1553+1)
	static int  __stdcall Local_Handle_61(unsigned int device)
	#include	"wt_1553b_handle.h"	 
#undef HANDLE_IDX

#define HANDLE_IDX	(7*nMax_CH1553+0)
	static int  __stdcall Local_Handle_70(unsigned int device)
	#include	"wt_1553b_handle.h"	 
#undef HANDLE_IDX
#define HANDLE_IDX	(7*nMax_CH1553+1)
	static int  __stdcall Local_Handle_71(unsigned int device)
	#include	"wt_1553b_handle.h"	 
#undef HANDLE_IDX

	
UINT WT_1553B_Init(UINT device,UINT reinit)
{
	if(Wtdriver_Open(device)==WT_SUCCESS)
	{
		Wtdriver_Read_PciConfig(device,&pci_config[device]);

		if(
				((pci_config[device].VendorID==0x5754)&&(pci_config[device].DeviceID==0x0642))
		  )
		{
		//printf("**********************\r\n");
			if(reinit==0)
			{
				if(pci_config[device].RevisionID==0x05)
				{
					if(WT_DM642_Init(device,0,0,"host:wt_cpci642_1553B_Prog.bin","host:wt_pci642_1553B.rbf",NULL)!=WT_SUCCESS)
					{
						logMsg("DM642 initial failed, can't find source files\r\n",0,0,0,0,0,0);
						return API_BAD_DEVICE_ID;
						/*wt_cpci642_1553B_Prog.bin,wt_pci642_1553B.rbf,dosfs only read the first section chars*/
						/*"/ata0a/wt_cpc~1.bin","/ata0a/wt_pci~1.rbf"*/
						/*"host:wt_cpci642_1553B_Prog.bin","host:wt_pci642_1553B.rbf"*/
					}	
				}
				else if(pci_config[device].RevisionID==0x0E)
				{
					if(WT_DM642_Init(device,0,0,"host:wt_cpci642_1553B_Prog.bin","host:wt_pxi642_1553B.rbf",NULL)!=WT_SUCCESS)
					{
						return API_BAD_DEVICE_ID;
					}	
				}
				else if(pci_config[device].RevisionID==0x81)
				{
					if(WT_DM642_Init(device,0,0,"host:wt_cpci642_1553B_Prog.bin","host:wt_cpci642_1553B_can.rbf",NULL)!=WT_SUCCESS)
					{
						return API_BAD_DEVICE_ID;
					}	
				}
				else if(pci_config[device].RevisionID==0xc0)
				{
					if(WT_DM642_Init(device,0,0,"host:wt_cpci642_1553B_Prog.bin","host:wt_cpci642_1553f.rbf",NULL)!=WT_SUCCESS)
					{
						return API_BAD_DEVICE_ID;
					}	
				}
				else return API_BAD_DEVICE_ID;
			}
			else
			{
				if(pci_config[device].RevisionID==0x05)
				{
					if(WT_DM642_ReInit(device,0,0,"host:wt_cpci642_1553B_Prog.bin","host:wt_pci642_1553B.rbf",NULL)!=WT_SUCCESS)
					{
						return API_BAD_DEVICE_ID;
						/*wt_cpci642_1553B_Prog.bin,wt_pci642_1553B.rbf,dosfs only read the first section chars*/
					}	
				}
				else if(pci_config[device].RevisionID==0x0E)
				{
					if(WT_DM642_ReInit(device,0,0,"host:wt_cpci642_1553B_Prog.bin","host:wt_pxi642_1553B.rbf",NULL)!=WT_SUCCESS)
					{
						return API_BAD_DEVICE_ID;
					}	
				}
				else if(pci_config[device].RevisionID==0x81)
				{
					if(WT_DM642_ReInit(device,0,0,"host:wt_cpci642_1553B_Prog.bin","host:wt_cpci642_1553B_can.rbf",NULL)!=WT_SUCCESS)
					{
						return API_BAD_DEVICE_ID;
					}	
				}
				else if(pci_config[device].RevisionID==0xc0)
				{
					if(WT_DM642_ReInit(device,0,0,"host:wt_cpci642_1553B_Prog.bin","host:wt_cpci642_1553f.rbf",NULL)!=WT_SUCCESS)
					{
						return API_BAD_DEVICE_ID;
					}	
				}
				else return API_BAD_DEVICE_ID;
			}

			pCmd[device] = (struct WT_DSP_Host_Cmd *)WT_DM642_Get_pHsotCmd(device);
			p1553b_card[device]=(struct WT_1553B_Board *)((unsigned int)pCmd[device]+pCmd[device]->hUser_Board);
			WT_1553B_Get_Board_Config(device,&WT1553_Mode[device*nMax_CH1553]);

			if(p1553b_card[device]->M1553B_Enable==0)
			{
				p1553b_card[device]->M1553B_Init_Req=1;
				while(p1553b_card[device]->M1553B_Init_Req){;}
			}

			Device_Init[device]=1;
			return API_SUCCESS;
		}
		else
		{
			return API_BAD_DEVICE_ID;
		}
	}
	else   return API_BAD_DEVICE_ID;
}

UINT WT_1553B_Exit(UINT device)
{
	UINT k=0;
	for(;k<nMaxHandle;k++)
	{
		pUserHandle[device*nMax_CH1553][k]=NULL;
		UserParam[device*nMax_CH1553][k]=NULL;
	}
	Wtdriver_Close(device);
	return 1;
}

//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////

//functions:

UINT __stdcall WT_1553B_FindDevice(UINT cardType,UINT Instance)
{
	UINT n;
	UINT k=0;
	UINT device=0;
	if(sem_flag==0)
    {
    	sync_sem = semBCreate(SEM_Q_PRIORITY,SEM_FULL );
		sem_flag = 1;
	}
	semTake(sync_sem,WAIT_FOREVER);
	n=sizeof(struct WT_DSP_Host_Cmd)+ nMax_CH1553*sizeof(struct	WT_1553B_Data);
	
	for(;device<nMaxDevice;device++)
	{
		if(Wtdriver_Open(device)==WT_SUCCESS)
		{
			Wtdriver_Read_PciConfig(device,&pci_config[device]);
			
			if((cardType==PCI1553)&&((pci_config[device].VendorID==0x5754)&&(pci_config[device].DeviceID==0x6205)&&(pci_config[device].RevisionID==0x40)))	
			{
				k++;
				if(k==Instance)
				{
					semGive(sync_sem);
					return device;
				}
			}
			else if((cardType==PCI1553)&&((pci_config[device].VendorID==0x5754)&&(pci_config[device].DeviceID==0x0642)&&(pci_config[device].RevisionID==0x05)))	
			{
				k++;
				if(k==Instance)
				{
				semGive(sync_sem);
					return device;
				}
			}
			
			else if((cardType==CPCI1553)&&((pci_config[device].VendorID==0x5754)&&(pci_config[device].DeviceID==0x0642)&&(pci_config[device].RevisionID==0x0E)))	
			{
				k++;
				if(k==Instance)
				{
				semGive(sync_sem);
					return device;
				}
			}
			else if((cardType==CPCI1553)&&((pci_config[device].VendorID==0x5754)&&(pci_config[device].DeviceID==0x0642)&&(pci_config[device].RevisionID==0x81)))	
			{
				k++;
				if(k==Instance)
				{
				semGive(sync_sem);
					return device;
				}
			}
			else if((cardType==CPCI1553)&&((pci_config[device].VendorID==0x5754)&&(pci_config[device].DeviceID==0x0642)&&(pci_config[device].RevisionID==0xc0)))	
			{
				k++;
				if(k==Instance)
				{
				semGive(sync_sem);
					return device;
				}
			}


		}
		else 
			{
			semGive(sync_sem);
			return -1;
			}
	}
	semGive(sync_sem);
	return -1;
}

UINT __stdcall WT_1553B_OpenChannel(UINT *chnd,UINT mode,UINT devid,UINT channel)
{
	UINT k=0;
	semTake(sync_sem,WAIT_FOREVER);
	if(devid<nMaxDevice)
	{
		if( (channel==CHANNEL_1)||(channel==CHANNEL_2) )
		{
			UINT cardnum=nMax_CH1553*devid+channel;
			if(Device_Init[devid]==1)
			{
				if((WT1553_Mode[cardnum]==Multi_Function)||(WT1553_Mode[cardnum]==Single_Function))
				{
					wt_1553B[cardnum]=(struct WT_1553B_Data *)((unsigned int)pCmd[devid]+p1553b_card[devid]->hM1553B+channel*sizeof(struct	WT_1553B_Data));

					irqfifo[cardnum]=wt_1553B[cardnum]->irqfifo;
					irqfifo_rdidx[cardnum]=wt_1553B[cardnum]->irqfifo_wridx;
					BM_Msg[cardnum]=wt_1553B[cardnum]->BM_Msg;
				}

					 if((devid==0)&&(channel==0))Wtdriver_SetUserHandle(0,Local_Handle_00);
				else if((devid==0)&&(channel==1))Wtdriver_SetUserHandle(0,Local_Handle_01);

				else if((devid==1)&&(channel==0))Wtdriver_SetUserHandle(1,Local_Handle_10);
				else if((devid==1)&&(channel==1))Wtdriver_SetUserHandle(1,Local_Handle_11);

				else if((devid==2)&&(channel==0))Wtdriver_SetUserHandle(2,Local_Handle_20);
				else if((devid==2)&&(channel==1))Wtdriver_SetUserHandle(2,Local_Handle_21);

				else if((devid==3)&&(channel==0))Wtdriver_SetUserHandle(3,Local_Handle_30);
				else if((devid==3)&&(channel==1))Wtdriver_SetUserHandle(3,Local_Handle_31);

				else if((devid==4)&&(channel==0))Wtdriver_SetUserHandle(4,Local_Handle_40);
				else if((devid==4)&&(channel==1))Wtdriver_SetUserHandle(4,Local_Handle_41);

				else if((devid==5)&&(channel==0))Wtdriver_SetUserHandle(5,Local_Handle_50);
				else if((devid==5)&&(channel==1))Wtdriver_SetUserHandle(5,Local_Handle_51);

				else if((devid==6)&&(channel==0))Wtdriver_SetUserHandle(6,Local_Handle_60);
				else if((devid==6)&&(channel==1))Wtdriver_SetUserHandle(6,Local_Handle_61);

				else if((devid==7)&&(channel==0))Wtdriver_SetUserHandle(7,Local_Handle_70);
				else if((devid==7)&&(channel==1))Wtdriver_SetUserHandle(7,Local_Handle_71);

				cardnum_map[cardnum]=cardnum;
				cardnum_device[cardnum]=devid;
				cardnum_ch[cardnum]=channel;
				Channle_Init[devid][channel]=1;
				for(k=0;k<nMaxHandle;k++)pUserHandle[cardnum][k]=NULL;
				*chnd=cardnum;
				wt_1553B[cardnum]->BC_Enable=0;
				wt_1553B[cardnum]->RT_Enable=0;
				wt_1553B[cardnum]->BM_Enable=0;
				semGive(sync_sem);
				return API_SUCCESS;
			}
			else
			{
				UINT status;
				if(channel==CHANNEL_1)	status=WT_1553B_Init(devid,1);
				else					status=WT_1553B_Init(devid,1);	

				if(status==API_SUCCESS)
				{
					if((WT1553_Mode[cardnum]==Multi_Function)||(WT1553_Mode[cardnum]==Single_Function))
					{
						wt_1553B[cardnum]=(struct WT_1553B_Data *)((unsigned int)pCmd[devid]+p1553b_card[devid]->hM1553B+channel*sizeof(struct	WT_1553B_Data));


						irqfifo[cardnum]=wt_1553B[cardnum]->irqfifo;
						irqfifo_rdidx[cardnum]=wt_1553B[cardnum]->irqfifo_wridx;
						BM_Msg[cardnum]=wt_1553B[cardnum]->BM_Msg;
					}
					
						 if((devid==0)&&(channel==0))Wtdriver_SetUserHandle(0,Local_Handle_00);
					else if((devid==0)&&(channel==1))Wtdriver_SetUserHandle(0,Local_Handle_01);

					else if((devid==1)&&(channel==0))Wtdriver_SetUserHandle(1,Local_Handle_10);
					else if((devid==1)&&(channel==1))Wtdriver_SetUserHandle(1,Local_Handle_11);

					else if((devid==2)&&(channel==0))Wtdriver_SetUserHandle(2,Local_Handle_20);
					else if((devid==2)&&(channel==1))Wtdriver_SetUserHandle(2,Local_Handle_21);

					else if((devid==3)&&(channel==0))Wtdriver_SetUserHandle(3,Local_Handle_30);
					else if((devid==3)&&(channel==1))Wtdriver_SetUserHandle(3,Local_Handle_31);

					else if((devid==4)&&(channel==0))Wtdriver_SetUserHandle(4,Local_Handle_40);
					else if((devid==4)&&(channel==1))Wtdriver_SetUserHandle(4,Local_Handle_41);

					else if((devid==5)&&(channel==0))Wtdriver_SetUserHandle(5,Local_Handle_50);
					else if((devid==5)&&(channel==1))Wtdriver_SetUserHandle(5,Local_Handle_51);

					else if((devid==6)&&(channel==0))Wtdriver_SetUserHandle(6,Local_Handle_60);
					else if((devid==6)&&(channel==1))Wtdriver_SetUserHandle(6,Local_Handle_61);

					else if((devid==7)&&(channel==0))Wtdriver_SetUserHandle(7,Local_Handle_70);
					else if((devid==7)&&(channel==1))Wtdriver_SetUserHandle(7,Local_Handle_71);


					cardnum_map[cardnum]=cardnum;
					cardnum_device[cardnum]=devid;
					cardnum_ch[cardnum]=channel;
					Channle_Init[devid][channel]=1;
					for(k=0;k<nMaxHandle;k++)pUserHandle[cardnum][k]=NULL;
					*chnd=cardnum;
					wt_1553B[cardnum]->BC_Enable=0;
					wt_1553B[cardnum]->RT_Enable=0;
					wt_1553B[cardnum]->BM_Enable=0;
					semGive(sync_sem);
					return API_SUCCESS;
				}
				else 
					{
					semGive(sync_sem);
					return API_BUSTOOLS_BADCARDNUM;
					}
			}
		}		
		else 
			{
			semGive(sync_sem);
			return API_BUSTOOLS_BADCARDNUM;
			}
	}
	else 
		{
		semGive(sync_sem);
		return API_BUSTOOLS_BADCARDNUM;
		}
}


UINT __stdcall WT_1553B_API_Init(UINT cardnum,UINT device)
{
	return WT_1553B_OpenChannel(&cardnum_map[cardnum],0,device,0);
}

UINT __stdcall WT_1553B_API_InitExtended(UINT cardnum,UINT device,UINT channel)
{
	return WT_1553B_OpenChannel(&cardnum_map[cardnum],0,device,channel);
}


//////////////////////////////////////////////////////////////////////////////

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     
UINT __stdcall WT_1553B_Close(UINT cardnum)
{
	UINT device,ch;
	semTake(sync_sem,WAIT_FOREVER);
	cardnum=cardnum_map[cardnum];

	device=cardnum_device[cardnum];
	ch=cardnum_ch[cardnum];
	Channle_Init[device][ch]=0;
	if((Channle_Init[device][0]==0)&&(Channle_Init[device][1]==0)) 
	{
		WT_1553B_Exit(device);

	}

	semGive(sync_sem);
	return API_SUCCESS;
}


UINT __stdcall WT_1553B_SetUserHandle(UINT cardnum,API_INT_FIFO *sIntFIFO)
{
	UINT k=0;
	semTake(sync_sem,WAIT_FOREVER);
	cardnum=cardnum_map[cardnum];

	sIntFIFO->head_index=0;
	sIntFIFO->tail_index=0;
	for(k=0;k<nMaxHandle;k++)
	{
		if(UserParam[cardnum][k]==NULL)
		{
			pUserHandle[cardnum][k]=(UserHandle)sIntFIFO->function;
			UserParam[cardnum][k]=sIntFIFO;
			if((sIntFIFO->FilterType&EVENT_RECORDER)==EVENT_RECORDER)
			{
				wt_1553B[cardnum]->BM_Record_Enable=1;
			}
			semGive(sync_sem);
			return API_SUCCESS;
		}
	}
	semGive(sync_sem);
	return API_BAD_DEVICE_ID;
}

UINT __stdcall WT_1553B_UnSetUserHandle(UINT cardnum,API_INT_FIFO *sIntFIFO)
{
	UINT k=0;
	semTake(sync_sem,WAIT_FOREVER);
	cardnum=cardnum_map[cardnum];

	for(k=0;k<nMaxHandle;k++)
	{
		if(UserParam[cardnum][k]==sIntFIFO)
		{
			pUserHandle[cardnum][k]=NULL;
			UserParam[cardnum][k]=NULL;
			semGive(sync_sem);
			return API_SUCCESS;
		}
	}
	semGive(sync_sem);
	return API_BAD_DEVICE_ID;
}
 
UINT __stdcall WT_1553B_Set_Voltage(UINT cardnum,BT_UINT voltage,BT_UINT coupling)
{
	semTake(sync_sem,WAIT_FOREVER);
	cardnum=cardnum_map[cardnum];

	if(voltage>1980)voltage=1980;

	wt_1553B[cardnum]->Voltage=(0xfff*voltage)/2000;
	wt_1553B[cardnum]->Set_Voltage=1;
	semGive(sync_sem);
	return API_SUCCESS;
}

UINT __stdcall WT_1553B_SetSa31(UINT cardnum,UINT sa31)
{
	cardnum=cardnum_map[cardnum];

	wt_1553B[cardnum]->SA31=sa31;
	wt_1553B[cardnum]->Set_SA31=1;
	return API_SUCCESS;
}

UINT __stdcall WT_1553B_GetSa31(UINT cardnum,UINT *sa31)
{
	cardnum=cardnum_map[cardnum];

	*sa31 = wt_1553B[cardnum]->SA31;
	return API_SUCCESS;
}

UINT __stdcall WT_1553B_BC_Init(UINT cardnum,WORD wRetry)
{
	semTake(sync_sem,WAIT_FOREVER);
	cardnum=cardnum_map[cardnum];

	if(WT1553_Mode[cardnum]==Multi_Function)
	{
		wt_1553B[cardnum]->BC_Enable=1;
		wt_1553B[cardnum]->BC_Retry=wRetry;
		semGive(sync_sem);
		return 1;
	}
	else 
	{
		if((wt_1553B[cardnum]->RT_Enable==0)&&(wt_1553B[cardnum]->BM_Enable==0))
		{
			wt_1553B[cardnum]->BC_Enable=1;
			wt_1553B[cardnum]->BC_Retry=wRetry;
			semGive(sync_sem);
			return 1;
		}
		else 
			{
			semGive(sync_sem);
			return 0; 
			}
	}
}

UINT __stdcall WT_1553B_BC_RetryInit(UINT cardnum, WORD *bc_retry)
{
	int i=0;
	cardnum=cardnum_map[cardnum];

	for(i=0;i<8;i++)wt_1553B[cardnum]->BC_Multiple_Retry[i]=bc_retry[i];
	return WT_SUCCESS;
}

UINT __stdcall WT_1553B_BC_Exit(UINT cardnum)
{
	cardnum=cardnum_map[cardnum];

	wt_1553B[cardnum]->BC_Enable=0;
	return WT_SUCCESS;
}

UINT  __stdcall WT_1553B_BC_Set_MBuf(UINT cardnum,struct WT_API_BC_MBUF *bc_msg)
{
	cardnum=cardnum_map[cardnum];

	if(bc_msg->messno<BCMsgNum)
	{
		memcpy((void *)&wt_1553B[cardnum]->BC_Msg[bc_msg->messno],bc_msg,sizeof(struct WT_API_BC_MBUF));
		//wt_1553B[cardnum]->BC_Msg[bc_msg->messno].control_611 |= BC_Control_MSG611_UPDATE;
		return WT_SUCCESS;
	}
	else return 0;
}

UINT  __stdcall WT_1553B_BC_Meesage_UpData(UINT cardnum,UINT block_id,unsigned short int *bc_data)
{
	cardnum=cardnum_map[cardnum];

	if(block_id<BCMsgNum)
	{
		memcpy((void *)&wt_1553B[cardnum]->BC_Msg[block_id].data[0],bc_data,32*sizeof(unsigned short int));
		//wt_1553B[cardnum]->BC_Msg[block_id].control_611 |= BC_Control_MSG611_UPDATE; 
		return API_SUCCESS;
	}
	else return API_BUSTOOLS_BADCARDNUM;
}

UINT  __stdcall WT_1553B_BC_Get_MBuf(UINT cardnum,struct WT_API_BC_MBUF *bc_msg)
{
	UINT k;
	cardnum=cardnum_map[cardnum];

	k=sizeof(struct WT_API_BC_MBUF);
	if(bc_msg->messno<BCMsgNum)
	{
		memcpy(bc_msg,(const void *)&wt_1553B[cardnum]->BC_Msg[bc_msg->messno],k);
		return WT_SUCCESS;
	}
	else return 0;
}

UINT  __stdcall WT_1553B_BC_mFrame_Run(UINT cardnum,UINT msgid,UINT period)
{
	semTake(sync_sem,WAIT_FOREVER);
	cardnum=cardnum_map[cardnum];
	
	if((wt_1553B[cardnum]->BC_Enable==1)&&(wt_1553B[cardnum]->mFrame_Run_Flag==0))
	{
		wt_1553B[cardnum]->mFrame_Run_Freq=24*period;
		wt_1553B[cardnum]->mFrame_Start_MsgID=msgid;
		wt_1553B[cardnum]->mFrame_Run_Start=1;
		semGive(sync_sem);
		return WT_SUCCESS;
	}
	else 	
		{
		semGive(sync_sem);
		return 0;
		}
}

UINT __stdcall WT_1553B_BC_mFrame_Stop(UINT cardnum)
{
	cardnum=cardnum_map[cardnum];

	if(wt_1553B[cardnum]->mFrame_Run_Flag==1)
	{
		wt_1553B[cardnum]->mFrame_Run_Stop=1;	
		return WT_SUCCESS;
	}
	return 0;
}

UINT __stdcall WT_1553B_BC_Async_Run(UINT cardnum,UINT Priority,UINT msgid)
{
	cardnum=cardnum_map[cardnum];

	if((wt_1553B[cardnum]->BC_Enable==1)&&(wt_1553B[cardnum]->Async_Is_Run==0))
	{
		wt_1553B[cardnum]->Async_Priority=Priority;
		wt_1553B[cardnum]->Async_Start_MsgID=msgid;
		wt_1553B[cardnum]->Async_Run_Start=1;
		while(wt_1553B[cardnum]->Async_Run_Start){;}
		return 1;
	}
	else	return 0;
}

UINT __stdcall WT_1553B_BC_AperiodicTest(UINT cardnum,UINT Priority)
{
	cardnum=cardnum_map[cardnum];

	return wt_1553B[cardnum]->Async_Is_Run;
}

UINT __stdcall WT_1553B_BC_Get_Status(UINT cardnum,UINT *mFrame_Status,UINT *Async_Status)
{
	cardnum=cardnum_map[cardnum];

	*mFrame_Status=wt_1553B[cardnum]->mFrame_Run_Flag;
	*Async_Status=wt_1553B[cardnum]->Async_Is_Run;
	return WT_SUCCESS;
}

UINT __stdcall WT_1553B_BC_AutoIncrMessageData(UINT cardnum,UINT messno,UINT data_wrd,UINT start, UINT incr,UINT rate,UINT max,UINT sflag)
{
	cardnum=cardnum_map[cardnum];

	if(sflag==1)
	{
		if(wt_1553B[cardnum]->BC_Msg[messno].auto_inc_flag==1) 
		{
			return API_BC_AUTOINC_INUSE;
		}
		else
		{
			wt_1553B[cardnum]->BC_Msg[messno].auto_inc_flag=1;
			wt_1553B[cardnum]->BC_Msg[messno].start_value=start;
			wt_1553B[cardnum]->BC_Msg[messno].inc_value=incr;
			wt_1553B[cardnum]->BC_Msg[messno].max_value=max;
			wt_1553B[cardnum]->BC_Msg[messno].inc_rate=rate;
			wt_1553B[cardnum]->BC_Msg[messno].word_idx=data_wrd;
			wt_1553B[cardnum]->BC_Msg[messno].inc_idx=0;
			wt_1553B[cardnum]->BC_Msg[messno].auto_inc_req=1;
			return API_SUCCESS;
		}
	}
	else
	{
		wt_1553B[cardnum]->BC_Msg[messno].auto_inc_flag=0;
		return API_SUCCESS;
	}
}


UINT __stdcall WT_1553B_BM_Init(UINT cardnum)
{
	cardnum=cardnum_map[cardnum];

	return WT_SUCCESS;
}

UINT __stdcall WT_1553B_BM_MessageAlloc(UINT cardnum,UINT mbuf_count,UINT *mbuf_actual,UINT enable)
{
	semTake(sync_sem,WAIT_FOREVER);

	cardnum=cardnum_map[cardnum];

    if(mbuf_count>BmNum)
	{
		 *mbuf_actual=BmNum;
	}
	else
	{
		 *mbuf_actual=mbuf_count;
	}
	wt_1553B[cardnum]->BM_Irq_Enable=enable;
	semGive(sync_sem);

	return WT_SUCCESS;
}

UINT __stdcall WT_1553B_BM_Start(UINT cardnum)
{
	semTake(sync_sem,WAIT_FOREVER);

	if(cardnum == -1)
	{
		semGive(sync_sem);
		return WT_SUCCESS;
	}
	cardnum=cardnum_map[cardnum];

	if(WT1553_Mode[cardnum]==Multi_Function)
	{
		wt_1553B[cardnum]->BM_Msg_WrIdx  = 0;
		bm_rdidx[cardnum]=0;
		wt_1553B[cardnum]->BM_Enable=1;
		bm_enable[cardnum]=1;
		semGive(sync_sem);
		return WT_SUCCESS;
	}
	
	else
	{
		if((wt_1553B[cardnum]->RT_Enable==0)&&(wt_1553B[cardnum]->BC_Enable==0))
		{
			wt_1553B[cardnum]->BM_Msg_WrIdx  = 0;
			bm_rdidx[cardnum]=0;
			wt_1553B[cardnum]->BM_Enable=1;
			bm_enable[cardnum]=1;
			semGive(sync_sem);
			return WT_SUCCESS;
		}
		semGive(sync_sem);
		return WT_UNSUCCESS;
	}
}


UINT __stdcall WT_1553B_BM_Stop(UINT cardnum)
{
	semTake(sync_sem,WAIT_FOREVER);

	cardnum=cardnum_map[cardnum];

	//wt_1553B[cardnum]->BM_Msg_WrIdx  = 0;
	//wt_1553B[cardnum]->BM_Msg_RdIdx  = 0;
	//bm_rdidx[cardnum]=0;
	wt_1553B[cardnum]->BM_Enable=0;
	semGive(sync_sem);
	return WT_SUCCESS;
}

UINT __stdcall WT_1553B_BM_Get_ID_Message(UINT cardnum,UINT mbuf_id,struct BM_Message *bm_msg)
{
	cardnum=cardnum_map[cardnum];

	mbuf_id&=BmMask;
	memcpy(bm_msg,(const void *)&BM_Msg[cardnum][mbuf_id],sizeof(struct WT1553_Msg));
	bm_msg->resp_time1 = (float)bm_msg->msg.respcnt1/24; 
	bm_msg->resp_time2 = (float)bm_msg->msg.respcnt2/24;
	return  WT_SUCCESS;
}

UINT __stdcall WT_1553B_BM_Get_Message(UINT cardnum,struct BM_Message *bm_msg)
{
	UINT rdidx;
	UINT wridx;
	semTake(sync_sem,WAIT_FOREVER);
   	if(cardnum == -1)return WT_SUCCESS;
	cardnum=cardnum_map[cardnum];

	rdidx=bm_rdidx[cardnum];
	wridx=wt_1553B[cardnum]->BM_Msg_WrIdx;
	if(wridx!=rdidx)
	{
		memcpy(bm_msg,(const void *)&BM_Msg[cardnum][rdidx],sizeof(struct WT1553_Msg));
		rdidx = (rdidx+1)&BmMask;
		bm_rdidx[cardnum]=rdidx;
		bm_msg->resp_time1 = (float)(bm_msg->msg.respcnt1/24); 
		bm_msg->resp_time2 = (float)(bm_msg->msg.respcnt2/24);
		semGive(sync_sem);
		return  WT_SUCCESS;
	}
	else	
		{
		semGive(sync_sem);
		return  API_BM_READ_NODATA;
		}
}

UINT __stdcall WT_1553B_BM_FilterWrite(UINT cardnum,UINT rtaddr,UINT subaddr,UINT tr,API_BM_CBUF * cbuf)
{
	cardnum=cardnum_map[cardnum];

	wt_1553B[cardnum]->BM_Cbuf[rtaddr][subaddr][tr].wcount=cbuf->t.wcount;
	wt_1553B[cardnum]->BM_Cbuf[rtaddr][subaddr][tr].modecode=cbuf->t.modecode;
	wt_1553B[cardnum]->BM_Cbuf[rtaddr][subaddr][tr].pass_count=cbuf->pass_count;
	return  WT_SUCCESS;
}

UINT __stdcall WT_1553B_BM_FilterRead(UINT cardnum,UINT rtaddr,UINT subaddr,UINT tr,API_BM_CBUF * cbuf)
{
	cardnum=cardnum_map[cardnum];

	cbuf->t.wcount=wt_1553B[cardnum]->BM_Cbuf[rtaddr][subaddr][tr].wcount;
	cbuf->t.modecode=wt_1553B[cardnum]->BM_Cbuf[rtaddr][subaddr][tr].modecode;
	cbuf->pass_count=wt_1553B[cardnum]->BM_Cbuf[rtaddr][subaddr][tr].pass_count;
	return  WT_SUCCESS;
}

UINT __stdcall WT_1553B_RT_Init(UINT cardnum)
{
	semTake(sync_sem,WAIT_FOREVER);

	if(cardnum == -1)
	{
		semGive(sync_sem);
		return WT_SUCCESS;
	}
	cardnum=cardnum_map[cardnum];

	if(WT1553_Mode[cardnum]==Multi_Function)
	{
		semGive(sync_sem);
		return WT_SUCCESS;
	}
	else 
	{
		if((wt_1553B[cardnum]->BC_Enable==0)&&(wt_1553B[cardnum]->BM_Enable==0))
		{
			wt_1553B[cardnum]->RT_Enable = 1;
			semGive(sync_sem);
			return WT_SUCCESS;
		}
		else 
			{
			semGive(sync_sem);
			return WT_BAD_DEVICE_ID; 
			}
	}
}

UINT __stdcall WT_1553B_RT_Start(UINT cardnum)
{
	semTake(sync_sem,WAIT_FOREVER);
	cardnum=cardnum_map[cardnum];

	if(WT1553_Mode[cardnum]==Multi_Function)
	{
		wt_1553B[cardnum]->RT_Start=1;
		semGive(sync_sem);
		return WT_SUCCESS;
	}
	else 
	{
		if((wt_1553B[cardnum]->BC_Enable==0)&&(wt_1553B[cardnum]->BM_Enable)==0)
		{
			wt_1553B[cardnum]->RT_Start=1;
			semGive(sync_sem);
			return WT_SUCCESS;
		}
		else 
			{
			semGive(sync_sem);
			return WT_BAD_DEVICE_ID; 
			}
	}
}

UINT __stdcall WT_1553B_RT_Stop(UINT cardnum)
{
	semTake(sync_sem,WAIT_FOREVER);

	cardnum=cardnum_map[cardnum];

	wt_1553B[cardnum]->RT_Stop=1;
	semGive(sync_sem);
	return WT_SUCCESS;
}

UINT __stdcall WT_1553B_RT_AbufWrite(UINT cardnum,UINT rtaddr,struct WT_API_RT_ABUF *pAbuf)
{
	semTake(sync_sem,WAIT_FOREVER);
	cardnum=cardnum_map[cardnum];

	memcpy((void *)&wt_1553B[cardnum]->RT_Abuf[rtaddr],pAbuf,sizeof(struct WT_API_RT_ABUF));
	wt_1553B[cardnum]->RT_Abuf_WR_Addr=rtaddr;
	wt_1553B[cardnum]->RT_Abuf_WR=1;
	while(wt_1553B[cardnum]->RT_Abuf_WR){;}
	semGive(sync_sem);
	return WT_SUCCESS;
}

UINT __stdcall WT_1553B_RT_AbufRead(UINT cardnum,UINT rtaddr,struct WT_API_RT_ABUF *pAbuf)
{
	semTake(sync_sem,WAIT_FOREVER);

	cardnum=cardnum_map[cardnum];

	memcpy(pAbuf,(const void *)&wt_1553B[cardnum]->RT_Abuf[rtaddr],sizeof(struct WT_API_RT_ABUF));
	semGive(sync_sem);
	return WT_SUCCESS;
}

UINT __stdcall WT_1553B_RT_CbufBroadWrite(UINT cardnum,UINT subaddr,UINT tr,struct WT_API_RT_CBUFBROAD *pCbufBoard)
{
	cardnum=cardnum_map[cardnum];

	memcpy((void *)&wt_1553B[cardnum]->RT_Cbufbroad[subaddr][tr],pCbufBoard,sizeof(struct WT_API_RT_CBUFBROAD));
	wt_1553B[cardnum]->RT_Cbufbroad_WR_SubAddr=subaddr;
	wt_1553B[cardnum]->RT_Cbufbroad_WR_TR=tr;
	wt_1553B[cardnum]->RT_Cbufbroad_WR=1;
	while(wt_1553B[cardnum]->RT_Cbufbroad_WR){;}
	return WT_SUCCESS;
}

UINT __stdcall WT_1553B_RT_CbufBroadRead(UINT cardnum,UINT subaddr,UINT tr,struct  WT_API_RT_CBUFBROAD *pCbufBoard)
{
	cardnum=cardnum_map[cardnum];

	memcpy(pCbufBoard,(const void *)&wt_1553B[cardnum]->RT_Cbufbroad[subaddr][tr],sizeof(struct WT_API_RT_CBUFBROAD));
	return WT_SUCCESS;
}

UINT __stdcall WT_1553B_RT_CbufWrite(UINT cardnum,UINT rtaddr,UINT subaddr,UINT tr,UINT count,struct WT_API_RT_CBUF *pCbuf)
{
	semTake(sync_sem,WAIT_FOREVER);
	cardnum=cardnum_map[cardnum];

	memcpy((void *)&wt_1553B[cardnum]->RT_Cbuf[rtaddr][subaddr][tr],pCbuf,sizeof(struct WT_API_RT_CBUF));
	wt_1553B[cardnum]->RT_Cbuf_WR_Addr=rtaddr;
	wt_1553B[cardnum]->RT_Cbuf_WR_SubAddr=subaddr;
	wt_1553B[cardnum]->RT_Cbuf_WR_TR=tr;
	wt_1553B[cardnum]->RT_Cbuf_WR_Count=count;
	wt_1553B[cardnum]->RT_Cbuf_WR=1;
	while(wt_1553B[cardnum]->RT_Cbuf_WR){;}
	semGive(sync_sem);
	return wt_1553B[cardnum]->RT_Cbuf_WR_Rst;
}

UINT __stdcall WT_1553B_RT_CbufRead(UINT cardnum,UINT rtaddr,UINT subaddr,UINT tr,UINT *count,struct WT_API_RT_CBUF *pCbuf)
{
	semTake(sync_sem,WAIT_FOREVER);

	cardnum=cardnum_map[cardnum];

	wt_1553B[cardnum]->RT_Cbuf_RD_Addr=rtaddr;
	wt_1553B[cardnum]->RT_Cbuf_RD_SubAddr=subaddr;
	wt_1553B[cardnum]->RT_Cbuf_RD_TR=tr;
	wt_1553B[cardnum]->RT_Cbuf_RD=1;
	while(wt_1553B[cardnum]->RT_Cbuf_RD){;}
	memcpy(pCbuf,(const void *)&wt_1553B[cardnum]->RT_Cbuf[rtaddr][subaddr][tr],sizeof(struct WT_API_RT_CBUF));
	*count=wt_1553B[cardnum]->RT_Cbuf_RD_Count;
	semGive(sync_sem);
	return WT_SUCCESS;
}

UINT __stdcall WT_1553B_RT_MessageWrite(UINT cardnum,UINT rtaddr,UINT subaddr,UINT tr,UINT msgid,struct WT_API_RT_MBUF *pmbuf)
{
	semTake(sync_sem,WAIT_FOREVER);
	cardnum=cardnum_map[cardnum];

	wt_1553B[cardnum]->RT_Mbuf_WR_Addr=rtaddr;
	wt_1553B[cardnum]->RT_Mbuf_WR_SubAddr=subaddr;
	wt_1553B[cardnum]->RT_Mbuf_WR_TR=tr;
	wt_1553B[cardnum]->RT_Mbuf_WR_ID=msgid;
	memcpy((void *)&wt_1553B[cardnum]->RT_Mbuf_WR_Param,pmbuf,sizeof(struct WT_API_RT_MBUF));
	wt_1553B[cardnum]->RT_Mbuf_WR=1;
	while(wt_1553B[cardnum]->RT_Mbuf_WR){;}

	if(wt_1553B[cardnum]->SA31==1)
	{
		if(subaddr==0)
		{
			wt_1553B[cardnum]->RT_Mbuf_WR_SubAddr=31;
			memcpy((void *)&wt_1553B[cardnum]->RT_Mbuf_WR_Param,pmbuf,sizeof(struct WT_API_RT_MBUF));
			wt_1553B[cardnum]->RT_Mbuf_WR=1;
			while(wt_1553B[cardnum]->RT_Mbuf_WR){;}
		}
		else if(subaddr==31)
		{
			wt_1553B[cardnum]->RT_Mbuf_WR_SubAddr=0;
			memcpy((void *)&wt_1553B[cardnum]->RT_Mbuf_WR_Param,pmbuf,sizeof(struct WT_API_RT_MBUF));
			wt_1553B[cardnum]->RT_Mbuf_WR=1;
			while(wt_1553B[cardnum]->RT_Mbuf_WR){;}
		}
	}
	semGive(sync_sem);
	return WT_SUCCESS;
}

UINT __stdcall WT_1553B_RT_MessageRead(UINT cardnum,UINT rtaddr,UINT subaddr,UINT tr,UINT msgid,struct WT_API_RT_MBUF *pmbuf)
{
	semTake(sync_sem,WAIT_FOREVER);
	cardnum=cardnum_map[cardnum];

	wt_1553B[cardnum]->RT_Mbuf_RD_Addr=rtaddr;
	wt_1553B[cardnum]->RT_Mbuf_RD_SubAddr=subaddr;
	wt_1553B[cardnum]->RT_Mbuf_RD_TR=tr;
	wt_1553B[cardnum]->RT_Mbuf_RD_ID=msgid;
	wt_1553B[cardnum]->RT_Mbuf_RD=1;
	while(wt_1553B[cardnum]->RT_Mbuf_RD){;}
	memcpy(pmbuf,(const void *)&wt_1553B[cardnum]->RT_Mbuf_RD_Param,sizeof(struct WT_API_RT_MBUF));
	semGive(sync_sem);
	return WT_SUCCESS;
}

UINT __stdcall WT_1553B_MemoryAlloc(UINT cardnum, UINT bcount,UINT * addr)
{
	cardnum=cardnum_map[cardnum];
	*addr=wt_1553B[cardnum]->buffer_offset;
	wt_1553B[cardnum]->buffer_offset+=bcount;
	if(wt_1553B[cardnum]->buffer_offset>131072)
			return API_BUSTOOLS_NO_MEMORY;
	else	return API_SUCCESS;
}

UINT __stdcall WT_1553B_MemoryWrite(UINT cardnum, UINT addr,UINT bcount,VOID * buff)
{
	cardnum=cardnum_map[cardnum];
	memcpy((void*)&wt_1553B[cardnum]->buffer[addr/2],buff,bcount);
	return API_SUCCESS;
}

UINT __stdcall WT_1553B_MemoryRead(UINT cardnum, UINT addr,UINT bcount,VOID * buff)
{
	cardnum=cardnum_map[cardnum];
	memcpy(buff,(void*)&wt_1553B[cardnum]->buffer[addr/2],bcount);
	return API_SUCCESS;
}

UINT __stdcall WT_1553B_BC_Set_Run_Mode(UINT cardnum,UINT run_mode)
{
	cardnum=cardnum_map[cardnum];

	wt_1553B[cardnum]->BC_Run_Mode=run_mode;
	return WT_SUCCESS;
}



